package com.brokendust.client.api.module.button;

import com.brokendust.client.PixelEngine;
import com.brokendust.client.api.module.GUIComponent;
import com.brokendust.client.api.module.PullPanelComponent;
import com.brokendust.client.api.util.BasePosition;
import com.brokendust.client.api.util.image.ImageControl;
import com.brokendust.client.config.module.ComponentJson;
import com.brokendust.client.config.module.button.ClickButtonJson;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.lwjgl.opengl.GL11;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.io.File;

public class ClickButton extends AbstractGui implements IGuiEventListener, GUIComponent, PullPanelComponent {
    public int guiWidth;
    public int guiHeight;
    public int guiDWidth;
    public int guiDHeight;
    public ResourceLocation imageOn;
    public ResourceLocation imageOff;
    public int objectWidthOn;
    public int objectHeightOn;
    public int objectWidthOff;
    public int objectHeightOff;
    public int x;
    public int y;
    public int position;
    public String display;
    public String object_id;
    public boolean switch_status;
    IPressable onPress;

    public ClickButton(ClickButtonJson clickButtonJson, int guiWidth, int guiHeight, int guiDWidth, int guiDHeight) {
        this.guiWidth = guiWidth;
        this.guiHeight = guiHeight;
        this.guiDWidth = guiDWidth;
        this.guiDHeight = guiDHeight;
        this.object_id = clickButtonJson.getObject_name();
        this.display = clickButtonJson.getDisplay_name();
        this.imageOn = ImageControl.getResourceLocation(clickButtonJson.getImage_on());
        this.imageOff = ImageControl.getResourceLocation(clickButtonJson.getImage_off());
        this.objectWidthOn = clickButtonJson.getWidth_on();
        this.objectHeightOn = clickButtonJson.getHeight_on();
        this.objectWidthOff = clickButtonJson.getWidth_off();
        this.objectHeightOff = clickButtonJson.getHeight_off();
        this.x = clickButtonJson.getX();
        this.y = clickButtonJson.getY();
        this.position = clickButtonJson.getPosition();
    }

    @Override
    public void upData(ComponentJson componentJson) {
        if (!(componentJson instanceof ClickButtonJson)) {
            return;
        }
        ClickButtonJson clickButtonJson = (ClickButtonJson) componentJson;
        this.display = clickButtonJson.getDisplay_name();
        this.imageOn = ImageControl.getResourceLocation(clickButtonJson.getImage_on());
        this.imageOff = ImageControl.getResourceLocation(clickButtonJson.getImage_off());
        this.objectWidthOn = clickButtonJson.getWidth_on();
        this.objectHeightOn = clickButtonJson.getHeight_on();
        this.objectWidthOff = clickButtonJson.getWidth_off();
        this.objectHeightOff = clickButtonJson.getHeight_off();
        this.x = clickButtonJson.getX();
        this.y = clickButtonJson.getY();
        this.position = clickButtonJson.getPosition();
    }

    @Override
    public void renderGUI(MatrixStack matrixStack, int mouseX, int mouseY, float particleTick, int guiX, int guiY) {
        Integer[] integers = BasePosition.getObjectPoint(guiX, guiY, this.guiWidth, this.guiHeight, this.objectWidthOff, this.objectHeightOff, this.x, this.y, this.position);
        int mX = integers[0];
        int mY = integers[1];
        this.switch_status = (mouseX >= mX && mouseY >= mY && mouseX < mX + this.objectWidthOn && mouseY < mY + this.objectHeightOn);
        RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
        if (this.switch_status) {
            PixelEngine.minecraft.getTextureManager().bind(this.imageOn);
            AbstractGui.blit(matrixStack, mX, mY, 0.0f, 0.0f, this.objectWidthOn, this.objectHeightOn, this.objectWidthOn, this.objectHeightOn);
        } else {
            PixelEngine.minecraft.getTextureManager().bind(this.imageOff);
            AbstractGui.blit(matrixStack, mX, mY, 0.0f, 0.0f, this.objectWidthOff, this.objectHeightOff, this.objectWidthOff, this.objectHeightOff);
        }
        FontRenderer fontrenderer = PixelEngine.minecraft.font;
        int j = 16777215;
        float alpha = 1.0f;
        AbstractGui.drawCenteredString(matrixStack, fontrenderer, this.display, mX + this.objectWidthOn / 2, mY + (this.objectHeightOn - 8) / 2, j | MathHelper.ceil(alpha * 255.0f) << 24);
    }

    @Override
    public void renderPull(MatrixStack matrixStack, int mouseX, int mouseY, float particleTick, int guiX, int guiY, int displayX, int displayY) {
        Integer[] integers = BasePosition.getObjectPoint(guiX, guiY, this.guiWidth, this.guiHeight, this.objectWidthOff, this.objectHeightOff, this.x, this.y, this.position);
        int mX = integers[0];
        int mY = integers[1];
        int mmX = mX + this.objectWidthOff;
        int mmY = mY + this.objectHeightOff;
        int ddX = displayX + this.guiDWidth;
        int ddY = displayY + this.guiDHeight;
        boolean withinRange = mX >= displayX - this.objectWidthOff && mX <= ddX && mmX >= displayX && mmX <= ddX + this.objectWidthOff;
        boolean withinRange2 = mY >= displayY - this.objectHeightOff && mY <= ddY && mmY >= displayY && mmY <= ddY + this.objectHeightOff;
        if (withinRange && withinRange2) {
            int cutX = 0;
            int cutMX = 0;
            if (mX < displayX) {
                cutX = displayX - mX;
                cutMX = displayX - mX;
                if (cutX > this.objectWidthOff) {
                    cutX = this.objectWidthOff;
                    cutMX = this.objectWidthOff;
                }
            }
            if (mmX > ddX) {
                cutX = mmX - ddX;
                if (cutX > this.objectWidthOff) {
                    cutX = this.objectWidthOff;
                }
            }
            int cutY = 0;
            int cutMY = 0;
            if (mY < displayY) {
                cutY = displayY - mY;
                cutMY = displayY - mY;
                if (cutY > this.objectHeightOff) {
                    cutY = this.objectHeightOff;
                    cutMY = this.objectHeightOff;
                }
            }
            if (mmY > ddY) {
                cutY = mmY - ddY;
                if (cutY > this.objectHeightOff) {
                    cutY = this.objectHeightOff;
                }
            }
            this.switch_status = (mouseX >= mX + cutMX && mouseY >= mY + cutMY && mouseX < mX + this.objectWidthOn + cutMX && mouseY < mY + this.objectHeightOn + cutMY);
            RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
            if (this.switch_status) {
                PixelEngine.minecraft.getTextureManager().bind(this.imageOn);
                AbstractGui.blit(matrixStack, mX + cutMX, mY + cutMY, (float) cutMX, (float) cutMY, this.objectWidthOn - cutX, this.objectHeightOn - cutY, this.objectWidthOn, this.objectHeightOn);
            } else {
                PixelEngine.minecraft.getTextureManager().bind(this.imageOff);
                AbstractGui.blit(matrixStack, mX + cutMX, mY + cutMY, (float) cutMX, (float) cutMY, this.objectWidthOff - cutX, this.objectHeightOff - cutY, this.objectWidthOff, this.objectHeightOff);
            }
            FontRenderer fontrenderer = PixelEngine.minecraft.font;
            GlStateManager._pushMatrix();
            double scale = Minecraft.getInstance().getWindow().getGuiScale();
            GlStateManager.glBlendFuncSeparate((int) (displayX * scale), (int) (displayY * scale), (int) (this.guiDWidth * scale), (int) (this.guiDHeight * scale));
            GL11.glEnable(3089);
            AbstractGui.drawCenteredString(matrixStack, fontrenderer, this.display, mX + this.objectWidthOn / 2, mY + (this.objectHeightOn - 8) / 2, 16777215);
            GL11.glDisable(3089);
            GlStateManager._popMatrix();
        }
    }

    public void onPress() {
        this.onPress.onPress(this);
    }

    public void setOnPress(IPressable onPress) {
        this.onPress = onPress;
    }

    public boolean mouseClicked(double mouseX, double mouseY, int state) {
        if (this.switch_status) {
            this.onPress();
            return true;
        }
        return false;
    }

    public void playDownSound(SoundHandler soundHandler) {
        soundHandler.play(SimpleSound.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f));
    }

    public void playSound() {
        try {
            String path = "assets/pixelengine/sounds/button.ogg";
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(path).getAbsoluteFile());
            Clip clip = AudioSystem.getClip();
            clip.open(audioInputStream);
            clip.start();
        } catch (Exception ex) {
            System.out.println("Error with playing sound.");
            ex.printStackTrace();
        }
    }

    @OnlyIn(Dist.CLIENT)
    public interface IPressable {
        void onPress(ClickButton p0);
    }
}
